/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.machineryrental.service.impl;

import cz.muni.fi.pa165.machineryrental.converters.CustomerDTOConverter;
import cz.muni.fi.pa165.machineryrental.converters.MachineDTOConverter;
import cz.muni.fi.pa165.machineryrental.converters.RentalDTOConverter;
import cz.muni.fi.pa165.machineryrental.dao.CustomerDAO;
import cz.muni.fi.pa165.machineryrental.dao.MachineDAO;
import cz.muni.fi.pa165.machineryrental.dao.RentalDAO;
import cz.muni.fi.pa165.machineryrental.dto.CustomerDTO;
import cz.muni.fi.pa165.machineryrental.dto.MachineDTO;
import cz.muni.fi.pa165.machineryrental.dto.RentalDTO;
import cz.muni.fi.pa165.machineryrental.entities.Customer;
import cz.muni.fi.pa165.machineryrental.entities.Machine;
import cz.muni.fi.pa165.machineryrental.entities.Rental;
import cz.muni.fi.pa165.machineryrental.service.RentalService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author David Katuscak, 359273
 */
@Service("RentalService")
@Component
public class RentalServiceImpl implements RentalService {

    @Autowired
    private CustomerDAO customerDAO;
	
    @Autowired
    private MachineDAO machineDAO;
	
    @Autowired
    private RentalDAO rentalDAO;

    public void setDAO(RentalDAO rentalDAO, CustomerDAO customerDAO, MachineDAO machineDAO) {
		if (rentalDAO == null) {
            throw new IllegalArgumentException("Given RentalDAO cannot be null.");
        }
        this.rentalDAO = rentalDAO;
        
        if (customerDAO == null) {
            throw new IllegalArgumentException("Given CustomerDAO cannot be null.");
        }
        this.customerDAO = customerDAO;
        
        if (machineDAO == null) {
            throw new IllegalArgumentException("Given MachineDAO cannot be null.");
        }
        this.machineDAO = machineDAO;
	}

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#getById(long) 
     */
    @Transactional(readOnly = true)
    public RentalDTO getById(long id) {
        if (id < 0) {
            throw new IllegalArgumentException("negative id");
        }

        Rental rental = rentalDAO.getById(id);
        if (rental == null) {
            return null;
        }
        
        return RentalDTOConverter.toDTO(rental);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#create(RentalDTO) 
     */
    @Transactional
    public void create(RentalDTO rental) {
        if (rental == null) {
            throw new IllegalArgumentException("null rental");
        }
        Rental entity = RentalDTOConverter.toEntity(rental);
        rentalDAO.create(entity);
        RentalDTOConverter.applyToDTO(rental, entity);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#update(RentalDTO)  
     */
    @Transactional
    public void update(RentalDTO rental) {
        if (rental == null) {
            throw new IllegalArgumentException("null rental");
        }
        if (rental.getId() <= 0) {
            throw new IllegalArgumentException("rental unexists");
        }
        
        Rental entity = RentalDTOConverter.toEntity(rental);

        rentalDAO.update(entity);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#remove(RentalDTO) 
     */
    @Transactional
    public void remove(RentalDTO rental) {
        if (rental == null) {
            throw new IllegalArgumentException("null rental");
        }
        if (rental.getId() <= 0) {
            throw new IllegalArgumentException("rental unexists");
        }

        Rental entity = RentalDTOConverter.toEntity(rental);
        rentalDAO.remove(entity);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findAll()  
     */
    @Transactional
    public List<RentalDTO> findAll() {
        List<Rental> rentals = rentalDAO.findAll();
        
        return RentalDTOConverter.toDTOList(rentals);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findByCustomer(Customer)  
     */
    @Transactional
    public List<RentalDTO> findByCustomer(CustomerDTO customer) {
        if (customer == null) {
            throw new IllegalArgumentException("null customer");
        }

        if (customer.getId() <= 0) {
            throw new IllegalArgumentException("user is not stored in the system");
        }

        List<Rental> rentals = rentalDAO.findByCustomer(
				CustomerDTOConverter.toEntity(customer));
        
        return RentalDTOConverter.toDTOList(rentals);
    }

    /**
     * @see cz.muni.fi.pa165.machineryrental.service.RentalService#findByMachine(Machine) 
     */
    @Transactional
    public List<RentalDTO> findByMachine(MachineDTO machine) {
        if (machine == null) {
            throw new IllegalArgumentException("null machine");
        }

        if (machine.getId() <= 0) {
            throw new IllegalArgumentException("machine is not stored in system");
        }

        List<Rental> rentals = rentalDAO.findByMachine(
				MachineDTOConverter.toEntity(machine));
        
        return RentalDTOConverter.toDTOList(rentals);
    }
    
	/**
     * Returns all existing rentals of given machine and customer.
     *
     * @param customer CustomerDTO, for which we want list of all rentals.
	 * @param machine MachineDTO, for which we want list of all rentals.
     * @return List of all rentals of given machine.
     * @throws IllegalArgumentException Throws if given machine is null.
	 * @throws IllegalArgumentException Throws if given customer is null.
     * @throws IllegalStateException Throws if manager is not initialized.
     */
	@Override
	public List<RentalDTO> findByCustomerMachine(CustomerDTO customer, MachineDTO machine) {
		
		if (machine == null) {
            throw new IllegalArgumentException("null machine");
        }
		
		if (customer == null) {
            throw new IllegalArgumentException("null customer");
        }

        if (machine.getId() <= 0) {
            throw new IllegalArgumentException("machine is not stored in system");
        }
		
		if (customer.getId() <= 0) {
            throw new IllegalArgumentException("customer is not stored in system");
        }

		Customer c = CustomerDTOConverter.toEntity(customer);
		Machine m = MachineDTOConverter.toEntity(machine);
		
        List<Rental> rentals = rentalDAO.findByCustomerMachine(c,m);
        
        return RentalDTOConverter.toDTOList(rentals);
		
	}
}
